Window窗口——窗口属性

1.窗口类型与层级

Android支持的窗口类型很多,不过我们可以将它们统一划分为三大类,即Application Window, System WindowSub Window。另外各个种类下还细分为若干子类型,且都在WindowManager.java 中定义,如下所示。

1. Application Window

普通应用程序的窗口都属于这一类,如表1-1所示。

1-1

Application Window 细分

TypeDescription

FIRST_APPLICATION_WINDOW= 1

应用程序窗口类型的起始值

TYPE_BASE_APPLICATION= 1

应用程序窗口类型的基础值,其他窗口类型以此为基础

TYPE_APPLICATION= 2

普通应用程序的窗口类型

TYPE_APPLICATION_STARTING= 3

应用程序的启动窗口类型。它不能由应用程序本身使用,而是Android系 统为应用程序启动前设计的窗口——当真正的应用窗口启动后就消失了

LAST_APPLICATION_WINDOW= 99

应用程序窗口类型的最大值

 

2. Sub Window

“Sub Window”的字面意思可以了解到,这类窗口将附着在其他Window中,因而被称为 “子窗口”。具体包括如下子类型,如表1-2所示。

1-2

Sub Window 细分

Type

Description

FIRST_SUB_WINDOW= 1000

子窗口类型的起始值

TYPE_APPLICATION_PANEL= FIRST_SUB_WINDOW

应用程序的panel子窗口,在它的父窗口之上显示

TYPE_APPLICATION_MED1A=

FIRST_SUB_WINDOW+1

用于显示多媒体内容的子窗口,位于父窗口之下

TYPE_APPLICATION_MED1A=FIRST_SUB_WINDOW+1

TYPE_APPLICATION_SUB_PANEL=

FIRST_SUB_WINDOW+2

也是一种panel子窗口,位于父窗口以及所有TYPE_APPLICATION_ PANEL子窗口之上

TYPE_APPLICATION_SUB_PANEL=FIRST_SUB_WINDOW+2

TYPE_APPLICAT1ON_ATTACHED_DIALOG=

FIRST_SUB_WINDOW+3

Dialog子窗口,如menu类型

TYPE_APPLICAT1ON_ATTACHED_DIALOG=FIRST_SUB_WINDOW+3

TYPE_APPLICATION_MED1A_OVERLAY=

FIRST_SUB_WINDOW+4

多媒体窗口的覆盖层,位于TYPE_APPLICATION_MEDIA和应用 程序窗口之间,通常需要是透明的才有意义。目前此类型处于未开 放状态

TYPE_APPLICATION_MED1A_OVERLAY=FIRST_SUB_WINDOW+4

LAST_SUB_WINDOW= 1999

子窗口类型的结束值

LAST_SUB_WINDOW= 1999

3. System Window

系统程序所釆用的窗口类型,细分如表1-3所示。

Type

Description

FIRST_SYSTEM_WINDOW = 2000;

系统窗口的起始值

TYPE_STATUS_BAR = FI RST_SYSTEM_ WINDOW;

系统状态栏窗口

TYPE_SEARCH_BAR = FIRST_SYSTEM_WINDOW+1;

搜索条窗口

TYPE_PHONE=FIRST_SYSTEM_WINDOW+2;

通话窗口,特别是来电通话。通常情况下它位 于系统状态栏之下,其他应用程序窗口之上

TYPE_SYSTEM_ALERT = FIRST_SYSTEM_WINDOW+3;

Alert窗口,如电量不足的警告窗口。通常都 位于所有其他应用程序之上

TYPE_KEYGUARD = FIRST_SYSTEM_WINDOW+4;

屏保窗口

TYPE_TOAST = FIRST_SYSTEM_WINDOW+5;

短暂的提示框窗口

TYPE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW+6;

系统覆盖层窗口,这种类型的窗口不能接收 input焦点,否则会与屏保发生冲突

TYPE_PRIORITY_PHONE = FIRST_SYSTEM_WINDOW+7;

电话优先窗口,如屏保状态下显示来电窗口

TYPE_SYSTEM_DIALOG = FIRST_SYSTEM_WINDOW+8;

比如RecentAppsDialog就是这种类型的窗口

TYPE_KEYGUARD_DIALOG = FIRST_SYSTEM_WlNDOW+9;

屏保时显示的对话框

TYPE_SYSTEM_ERROR = FIRST_SYSTEM_WINDOW+lO;

系统错误窗口

TYPEJNPUT_METHOD = FIRST_SYSTEM_WINDOW+11;

输入法窗口

TYPE_INPUT_METHOD_DIALOG = FIRST_SYSTEM_WINDOW+12;

输入法窗口之上的对话框式窗口

TYPE_WALLPAPER = FIRST_SYSTEM_WINDO W+13;

壁纸窗口

TYPE_STATUS_BAR_PANEL = FIRST_SYSTEM_WINDOW+14;

滑动状态栏出现的窗口

TYPE_SECURE_SYSTEM_OVERLAY=FIRST_SYSTEM1WINDOW+15;

TYPE_DRAG= FIRST_S YSTEM_W(NDO W+16;

TYPE_STATUS_BAR_SUB_PANEL= FIRST_SYSTEM_WINDOW+17;

TYPE_POINTER= FIRST_S YSTEM_WINDO W+18;

3种类型

暂未开放

TYPE_NAVIGATION_BAR = FIRST_SYSTEM_WINDOW+19;

导航条,可以参见本书应用篇的System UI 章节

TYPE_VOLUME_OVERLAY = FIRST_SYSTEM_WINDOW+20;

系统音量条

TYPE_BOOT_PROGRESS = FIRST_SYSTEM_WINDOW+21;

启动时的进度条窗口

TYPE_HIDDEN_NAV_CONSUMER = FIRST_SYSTEM_WINDOW+22;

当导航条隐藏时用于消耗触摸事件的伪窗口

TYPE_DREAM= FIRST_SYSTEM_WlNDOW+23;

TYPE NAVIGATlON BAR PANEL=FIRST SYSTEM WINDOW+24;

暂未开放

TYPE_UNIVERSE_BACKGROUND = FIRST_SYSTEM_WlNDOW+25;

在多用户系统中,将显示给所有用户

TYPE_DISPLAY_OVERLAY = FIRST_SYSTEM_WINDOW+26;

用于模拟第二个显示设备

TYPE_MAGNIFICAT1ON_OVERLAY = FIRST_SYSTEM_WINDOW+27;

有点类似于“放大镜”的效果,用于放大显 示某部分内容

TYPE_RECENTS_OVERLAY = FI RST_S YSTEM_ WINDO W+28;

TYPE_SYSTEM_DIALOG 基本一致,区 別是 TYPE_RECENTS_OVERLAY 只显示 在一个用户的屏幕上

LAST_SYSTEM_WINDOW = 2999;

系统窗口结束

每种子类型后面都有一个数值,代表了它的窗口类型值。比如TYPE_STATUS_BAR= FIRST_ SYSTEM_WINDOW=2000。三大窗口类型的间隔是:

Application Window: 1-99

Sub Window: 1000-1999

System Window: 2000-2999

 2.窗口属性(LayoutParams )

除了 WindowType外WMS中还牵涉到很多其他的窗口属性。开发者可以通过设置不同的属性来使UI界面显示出各种样式——它们就像窗口用户与WMS间的协议一样,WMS就是为了实现 这些用户需求而努力的。另外,了解这些属性的含义也能帮助我们更好地理解WMS的内部原理。

这些属性统一放置在WindowManager.LayoutParams中,接下来我们分析其中几个重要的变量。

1.Type

也就是窗口类型,不再赘述。

2.Flags

窗口的标志,默认值是0。目前Android 4.3系统上支持的flag标志以及含义如表1.4所示。

1-4 窗口标志释义

Flags

Description

FLAG_ALLOW_LOCK_WHILE_SCREEN_ON

只要此窗口可见,即便屏幕处于开启状态也允许锁屏

FLAG_DIM_BEHFND

在窗口后面的所有东西都将变暗淡(dimmed)

FLAG_NOT_FOCUSABLE

此窗口不获得输入焦点,意味着事件将发给该窗口后面的其他窗口。在 设置了此标志的同时,FLAG NOT TOUCH MODAL也会被同时设置

FLAG_NOT_TOUCHABLE

和上面的标志类似,它表示该窗口不接受任何触摸事件

FLAG_NOT_TOUCH_MODAL

“无模式”的窗口。也就是说,在该窗口区域外的pointer事件将传给 它后面其他窗口,而不是由它自己来处理这些事件

FLAG_TOUCHABLE_WHEN_WAK1NG

当设备进入睡眠状态时,设置此标志可以使你获得第一次的触摸事件 (因为这时候用户并不知道他们点击的是屏幕上的哪个位置,所以通 常这一事件是由系统自动处理的)

FLAG_KEEP_SCREEN_ON

只要这个窗口可见,屏幕就亮着

FLAG_LAYOUTJN_SCREEN

窗口显示时不考虑系统装饰窗(比如Status Bar)

FLAG LAYOUT NO LIMITS

允许窗口超过屏幕区域

FLAG_FULLSCREEN

隐藏所有的屏幕装饰窗口,切Status Bar这对于视频播放器之类的应 用程序是很有用的

FLAG_FORCE_NOT_FULLSCREEN

和上面的标志相反

FLAG_SECURE

窗口内容被认为是保密的,因而它不会出现在截屏中,也不会在不安 全的屏幕上显示

FLAG_SCALED

按照用户提供的参数做相应的伸缩调整

FLAG_IGNORE_CHEEK_PRESSES

有的时候用户和屏幕会贴得很近,如打电话时。这种情况下岀现的某 些事件有可能是“无意”的,不应该响应

FLAG_LAYOUT_INSET_DECOR

只能和FLAG_LAYOUTN_SCREEN一起使用。当设置了 “全屏显示" 布局时,应用祖口部分&容而然可能会被系统装饰窗口覆盖。如果同时设 置了这一标志,系统将充分考虑装饰窗口所占的区域,以防止上述情况

FLAG_SHOW_WHEN_LOCKED

使窗口能在锁屏窗口之上显示

FLAG_SHOW_WALLPAPER

让壁纸在这个窗口之后显示。换句话说,当窗口是透明或半透明时就 可以看到后面的壁纸背景(如Launcher)

FLAG_TURN_SCREEN_ON

窗口显示时将屏幕点亮

FLAG_DISMISS_KEYGUARD

设置这个标志可以解除屏幕锁,只要它不是一个secure lock

FLAG_HARDWARE_ACCELERATED

指明窗口是否需要硬件加速。当然,设置了这一标志并不能保证窗口 一定会得到硬件加速(取决于设备配置等一系列因素)

可以通过以下方法来设置一个窗口标志:

Window w = activity.getWindow();
w.setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);

3. systemUiVisibility

从名称可以看出,这个变量表示的是系统UI的可见性。

要特别注意的是,SystemUiVisibility的可选Flags值定义在View类中,而不是WindowManager, 具体如表1-5所示。

1-5 SystemUiVisibility 部分标志释义

Flags

Description

SYSTEM_U1_FLAG_VISIBLE

View视图请求显示System UI

SYSTEM_U1_FLAG_LOW_PROFILE

View 请求进入low profile M 模式 意味着 Status Bar/Navigation icons有可能会被调暗。通常游戏、电子书阅读器等应用程序会有此模式需求

SYSTEM _U1_FLAG_HIDE_NAVIGATION

这个标志用于请求Navigation Bar的隐藏。这个标志经常与FLAG_LAYOUT_IN_SCREENFLAG_LAYOUT_IN_SCREEN 一起使用,这样才能使应用程序UI内容真正的全屏显示

SYSTEM_UI_FLAG_FULLSCREEN

整个 View将进入全屏显示。它和 WindowManager.LayoutParams. FLAG_ FULLSCREEN的视觉效果基本一致。不过和Window提供的标志不同的是,对于使用 Window.FEATURE_ACTION_BAR_OVERLAY ActionBar, SystemUi中的这个标志同样能使它隐藏。

根据经验,如果是暂态的全屏显示需求,可以采用SYSTEM_UI_FLAG_ FULLSCREEN而如果是长时间的全屏显示,如游戏开发而靠,就 最好使用Window标志

SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN

参见本小节最后的范例。读者要注意区分它和SYSTEM_UI_FLAG_ FULLSCREEN 的差异

SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION

和上面标志的意义是类似的

SYSTEM_U1_FLAG_LAYOUT_STABLE

系统将尽量保持U1布局的稳定性

由前面的分析可知,我们只能对一个View (而不是Window)设置它的systemUiVisibility如果你希望某个Activity中的整棵View树都使用同一个systemUiVisibility,可以在ActivityonCreate中加入类似于如下的代码段(在调用setContentView前):

int newVis = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
getWindow().getDecorView().setSystemUiVisibility(newVis);

默认情况下,系统是从StatusBar下面的部分开始给应用程序做UI布局的。而上述这段代码 的目的就是使Activity以整个屏幕来布局——最为关键的是,同时还要显示StatusBar显然 FLAG_FULLSCREEN不能符合这个需求(因为它会隐藏系统的装饰部分,包括StatusBar)SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN这个标志会保留包括StatusBar在内的系统窗口, 同时会让View全屏显示。换句话说,你的View界面布局是从屏幕的(0,0)坐标开始的,但屏幕上方的一小部分内容会被StatusBar所遮盖。

那么,在什么场景下我们需要做这样的处理呢?

举个例子,现在很多定制手机的StatusBar是透明的。如果应用程序按照正常的做法从 StatusBar以下的位置开始布局,那么用户透过StatusBar看到的“画面”就是“黑的”:而如果从 (0,0)位置开始布局,那么用户就可以透过StatusBar看到应用程序的部分“View”内容了。另外, 有的应用程序需要频繁地在“显示系统装饰窗口”和“隐藏系统装饰窗口”间切换,为了让这两种情况下View本身的布局保持不变,也可以使用这一标志。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值